home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CreatingGames / Utilities / Misc / GraphicsCode / iff_library_23_2 / examples / GrabScreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-24  |  7.8 KB  |  350 lines

  1. /*
  2. **
  3. **    $Id: GrabScreen.c,v 23.2 93/05/24 15:43:28 chris Exp $
  4. **    $Revision: 23.2 $
  5. **
  6. **    $Filename: Examples/GrabScreen.c $
  7. **    $Author: Christian A. Weber $
  8. **    $Release: 23.2 $
  9. **    $Date: 93/05/24 15:43:28 $
  10. **
  11. **    IFF library example program. Compile with SAS/C 5.x or newer.
  12. **    This program saves the contents of the frontmost screen as an IFF file
  13. **    with filename 'RAM:grabscreen.pic'.
  14. **    This example makes use of the IFFL_PushChunk() / IFFL_WriteChunkBytes() /
  15. **    IFFL_PopChunk() functions, it does not use IFFL_SaveBitMap().
  16. **
  17. **    COPYRIGHT (C) 1987-1993 BY CHRISTIAN A. WEBER, BRUGGERWEG 2,
  18. **    CH-8037 ZUERICH, SWITZERLAND.
  19. **    THIS FILE MAY BE FREELY DISTRIBUTED. USE AT YOUR OWN RISK.
  20. **
  21. */
  22.  
  23. #include <proto/exec.h>
  24. #include <exec/memory.h>
  25. #include <proto/graphics.h>
  26. #include <graphics/gfxbase.h>
  27. #include <proto/intuition.h>
  28. #include <intuition/intuitionbase.h>
  29. #include <dos/dos.h>
  30.  
  31. #include <stdio.h>
  32.  
  33. #include <libraries/iff.h>        /* IFF library include file */
  34.  
  35. /*
  36. **    Flags that should be masked out of old 16-bit CAMG before save or use.
  37. **    Note that 32-bit mode id (non-zero high word) bits should not be twiddled
  38. */
  39. #define OLDCAMGMASK  (~(SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO))
  40.  
  41. #define MAXSAVEDEPTH        24
  42. #define BODYBUFSIZE            10000
  43. #define MAXPACKEDSIZE(s)    ((s)*2)
  44.  
  45. /*
  46. **    Masking techniques
  47. */
  48. #define    mskNone                    0
  49. #define    mskHasMask                1
  50. #define    mskHasTransparentColor    2
  51. #define    mskLasso                3
  52.  
  53. /*
  54. **    Compression techniques
  55. */
  56. #define    cmpNone                    0
  57. #define    cmpByteRun1                1
  58.  
  59.  
  60. /****************************************************************************
  61. **    Globals
  62. */
  63.  
  64. struct Library    *IFFBase;
  65. char            version[] = "\0$VER: GrabScreen 22.4 by Christian A. Weber";
  66.  
  67.  
  68. /****************************************************************************
  69. **    This is an example implementation of an IFF writer. It writes the
  70. **    contents of a screen to an IFF ILBM file.
  71. **    Basically, this routine does the same as IFFL_SaveBitMap(), but it is
  72. **    here anyway to show you how to write an IFF file using iff.library's
  73. **    generic write functions.
  74. */
  75.  
  76. BOOL MySaveScreen(struct Screen *screen,char *filename)
  77. {
  78.     IFFL_HANDLE        iff;
  79.     struct BitMap    *bitmap = &screen->BitMap;
  80.     BOOL            result = FALSE;
  81.  
  82.     /*
  83.     **    Open the file for writing
  84.     */
  85.     if (iff = IFFL_OpenIFF(filename, IFFL_MODE_WRITE) )
  86.     {
  87.         struct IFFL_BMHD    bmhd;
  88.         ULONG                modeid;
  89.         UBYTE                *colortable;
  90.         int                    count;
  91.  
  92.         /*
  93.         **    Prepare the BMHD structure
  94.         */
  95.         bmhd.w                    = screen->Width;    
  96.         bmhd.h                    = screen->Height;
  97.         bmhd.x                    = screen->LeftEdge;        /* Not very useful :-) */
  98.         bmhd.y                    = screen->TopEdge;
  99.         bmhd.nPlanes            = bitmap->Depth;
  100.         bmhd.masking            = mskNone;
  101.         bmhd.compression        = cmpByteRun1;
  102.         bmhd.pad1                = 0;
  103.         bmhd.transparentColor    = 0;
  104.         bmhd.xAspect            = screen->Width;
  105.         bmhd.yAspect            = screen->Height;
  106.         bmhd.pageWidth            = screen->Width;
  107.         bmhd.pageHeight            = screen->Height;
  108.  
  109.         /*
  110.         **    Create the BMHD chunk. (goto considered useful :-))
  111.         */
  112.         if (IFFL_PushChunk(iff, ID_ILBM, ID_BMHD) )
  113.         {
  114.             if (!IFFL_WriteChunkBytes(iff, &bmhd, sizeof(bmhd)) )
  115.             {
  116.                 printf("Error writing BMHD data.\n");
  117.                 goto error;
  118.             }
  119.  
  120.             if (!IFFL_PopChunk(iff) )
  121.             {
  122.                 printf("Error closing BMHD chunk.\n");
  123.                 goto error;
  124.             }
  125.         }
  126.         else
  127.         {
  128.             printf("Error creating BMHD chunk.\n");
  129.             goto error;
  130.         }
  131.  
  132.         /*
  133.         **    Create the CMAP chunk.
  134.         */
  135.         count = screen->ViewPort.ColorMap->Count;
  136.         if (colortable = AllocMem(count * 3, MEMF_ANY))
  137.         {
  138.             int i;
  139.  
  140.             for (i=0; i<count; ++i)
  141.             {
  142.                 UWORD rgb4 =  GetRGB4(screen->ViewPort.ColorMap, i);
  143.  
  144.                 colortable[i*3+0]  = (rgb4 >> 4) & 0xF0;
  145.                 colortable[i*3+0] |= colortable[i*3+0] >> 4;
  146.  
  147.                 colortable[i*3+1]  = (rgb4     ) & 0xF0;
  148.                 colortable[i*3+1] |= colortable[i*3+1] >> 4;
  149.  
  150.                 colortable[i*3+2]  = (rgb4 << 4) & 0xF0;
  151.                 colortable[i*3+2] |= colortable[i*3+2] >> 4;
  152.             }
  153.  
  154.             if (IFFL_PushChunk(iff, ID_ILBM, ID_CMAP) )
  155.             {
  156.                 if (!IFFL_WriteChunkBytes(iff, colortable, count * 3) )
  157.                 {
  158.                     printf("Error writing CMAP data.\n");
  159.                     goto error;
  160.                 }
  161.  
  162.                 if (!IFFL_PopChunk(iff) )
  163.                 {
  164.                     printf("Error closing CMAP chunk.\n");
  165.                     goto error;
  166.                 }
  167.             }
  168.             else
  169.             {
  170.                 printf("Error creating CMAP chunk.\n");
  171.                 goto error;
  172.             }
  173.  
  174.             FreeMem(colortable, count * 3);
  175.         }
  176.  
  177.         /*
  178.         **    Get the viewport's modes for the CAMG chunk.
  179.         */
  180.         modeid = (GfxBase->LibNode.lib_Version >= 36) ?
  181.             GetVPModeID(&screen->ViewPort) : (screen->ViewPort.Modes & OLDCAMGMASK);
  182.  
  183.         if (IFFL_PushChunk(iff, ID_ILBM, ID_CAMG) )
  184.         {
  185.             if (!IFFL_WriteChunkBytes(iff, &modeid, sizeof(modeid)) )
  186.             {
  187.                 printf("Error writing CAMG data.\n");
  188.                 goto error;
  189.             }
  190.  
  191.             if (!IFFL_PopChunk(iff) )
  192.             {
  193.                 printf("Error closing CAMG chunk.\n");
  194.                 goto error;
  195.             }
  196.         }
  197.         else
  198.         {
  199.             printf("Error creating CAMG chunk.\n");
  200.             goto error;
  201.         }
  202.  
  203.         /*
  204.         **    Generate BODY
  205.         */
  206.         if (IFFL_PushChunk(iff, ID_ILBM, ID_BODY) )
  207.         {
  208.             UBYTE    *bodybuf;
  209.  
  210.             if (bodybuf = AllocMem(BODYBUFSIZE, MEMF_ANY) )
  211.             {
  212.                 UBYTE    *planes[MAXSAVEDEPTH];
  213.                 int        row, rowbytes, iplane, bodysize=0;
  214.  
  215.                 /*
  216.                 **    Under OS 3.x, we are not allowed to read the fields of a
  217.                 **    BitMap structure directly (strange results may happen due
  218.                 **    to ILBM modes), so we call GetBitMapAttr() under 3.x.
  219.                 */
  220.                 rowbytes = (GfxBase->LibNode.lib_Version >= 39) ?
  221.                     (GetBitMapAttr(bitmap, BMA_WIDTH) >> 3) :
  222.                     bitmap->BytesPerRow;
  223.  
  224.                 /*
  225.                 **    Copy the plane pointers into the local array "planes"
  226.                 */
  227.                 for (iplane=0; iplane < bmhd.nPlanes; ++iplane)
  228.                 {
  229.                     planes[iplane] = bitmap->Planes[iplane];
  230.                 }
  231.  
  232.                 for (row=0; row < bmhd.h; ++row)
  233.                 {
  234.                     for (iplane=0; iplane < bmhd.nPlanes; ++iplane)
  235.                     {
  236.                         int comprsize;
  237.  
  238.                         /*
  239.                         **    To speed up things, we collect as much data
  240.                         **    as possible in bodybuf before we write it out.
  241.                         */
  242.                         if (bodysize > (BODYBUFSIZE-MAXPACKEDSIZE(rowbytes)) )
  243.                         {
  244.                             if (!IFFL_WriteChunkBytes(iff, bodybuf, bodysize) )
  245.                             {
  246.                                 printf("Error writing BODY data.\n");
  247.                                 goto error;
  248.                             }
  249.                             bodysize = 0;
  250.                         }
  251.  
  252.                         /*
  253.                         **    Compress the next row
  254.                         */
  255.                         if ( !(comprsize = IFFL_CompressBlock(planes[iplane],
  256.                                 bodybuf+bodysize, rowbytes, IFFL_COMPR_BYTERUN1)) )
  257.                         {
  258.                             printf("Error compressing BODY data.\n");
  259.                             goto error;
  260.                         }
  261.                         bodysize        += comprsize;
  262.                         planes[iplane]    += bitmap->BytesPerRow; /* next line */
  263.                     }
  264.                 }
  265.  
  266.                 /*
  267.                 **    Now we're done, so flush the body data buffer
  268.                 */
  269.                 if (bodysize)
  270.                 {
  271.                     if (!IFFL_WriteChunkBytes(iff, bodybuf, bodysize) )
  272.                     {
  273.                         printf("Error writing BODY data.\n");
  274.                         goto error;
  275.                     }
  276.                 }
  277.  
  278.                 FreeMem(bodybuf, BODYBUFSIZE);
  279.             }
  280.             else
  281.             {
  282.                 printf("No memory for BODY buffer.\n");
  283.                 goto error;
  284.             }
  285.  
  286.             if (!IFFL_PopChunk(iff) )
  287.             {
  288.                 printf("Error closing BODY chunk.\n");
  289.                 goto error;
  290.             }
  291.  
  292.             /*
  293.             **    If we get here, everything was fine.
  294.             */
  295.             result = TRUE;
  296.         }
  297.         else
  298.         {
  299.             printf("Error creating BODY chunk.\n");
  300.             goto error;
  301.         }
  302. error:
  303.         IFFL_CloseIFF(iff);
  304.     }
  305.  
  306.     return result;
  307. }
  308.  
  309.  
  310. /****************************************************************************
  311. **    Main program
  312. */
  313.  
  314. int main(int argc, char **argv)
  315. {
  316.     int result = RETURN_FAIL;
  317.  
  318.     if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L) )
  319.     {
  320.         if (IntuitionBase = (void *)OpenLibrary("intuition.library", 0) )
  321.         {
  322.             /*
  323.             **    For the new functions we need at least version 21 of iff.library.
  324.             */
  325.             if (IFFBase = OpenLibrary(IFFNAME, 21L) )
  326.             {
  327.                 /*
  328.                 **    Note that we don't lock the screen, so it might go away while
  329.                 **    we're writing its contents to the file, and the picture may
  330.                 **    then contain garbage.
  331.                 */
  332.                 MySaveScreen(IntuitionBase->FirstScreen, "RAM:grabscreen.pic");
  333.                 result = RETURN_OK;
  334.  
  335.                 CloseLibrary(IFFBase);
  336.             }
  337.             else printf("Can't open iff.library V21+\n");
  338.  
  339.             CloseLibrary(IntuitionBase);
  340.         }
  341.         else printf("Can't open intuition.library!\n");
  342.  
  343.         CloseLibrary(GfxBase);
  344.     }
  345.     else printf("Can't open graphics.library!\n");
  346.  
  347.     return result;
  348. }
  349.  
  350.